package com.abe.bathsystem.android.v3;

import android.view.View;
import android.widget.TextView;

import com.abe.bathsystem.base.ManagerLocalData;
import com.abe.bathsystem.entity.serial.DeviceControlEntity;
import com.abe.bathsystem.entity.serial.DeviceTemperatureEntity;
import com.abe.bathsystem.entity.serial.DeviceWaterUsageEntity;
import com.abe.bathsystem.entity.serial.SerialCommandEntity;
import com.abe.bathsystem.entity.serial.SerialDataEntity;
import com.abe.bathsystem.utils.SerialPortParse;
import com.abe.bathsystem.utils.SerialPortUtils;
import com.abe.libcore.utils.normal.CommonUtils;
import com.abe.libcore.utils.normal.ConstantCore;
import com.abe.libcore.utils.normal.ThreadPoolUtils;
import com.abe.libcore.utils.normal.ToastUtils;
import com.google.gson.Gson;

import net.yet.campusdev.R;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

public abstract class MainBathSerialPortActivity extends MainBathAdActivity {

    //重启串口
    private boolean isResetSerialPort = false;
    //命令集合
    private List<SerialCommandEntity> commandList = new ArrayList<>();
    //标识
    private boolean isSerialPortRun = false, isCommandRun = false;

    //获取到位置用户用水量后的分发处理
    protected abstract void showBathPosWaterUsage(int pos, DeviceWaterUsageEntity entity);

    // 获取到传感器温度后的分发处理
    protected abstract void showBathPosTemperature(DeviceTemperatureEntity entity);

    //正在使用大屏操作的用户位置
    protected int currentDeviceEndPos = -1;

    @Override
    public void initContent() {
        super.initContent();
        if (ManagerLocalData.isUseSerialPort()) {
            openSerialPort();
        } else {
            localSendMessage(APP_TOAST, "不启用串口");
        }
    }

    //打开串口
    private void openSerialPort() {
        isSerialPortRun = false;
        isCommandRun = false;
        if (ManagerLocalData.getSerialPort().equals(SerialPortUtils.path_ttys0)) {
            serialPortPresenter().openSerialPort(SerialPortUtils.SerialPort_ttys0);
        } else {
            serialPortPresenter().openSerialPort(SerialPortUtils.SerialPort_ttysOther);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        serialPortPresenter().closeSerialPort();
    }

    @Override
    protected void resetSerialPort() {
        isResetSerialPort = true;
        serialPortPresenter().closeSerialPort();
    }

    //pos从0开始,发送位置用户订单结束命令
    protected void sendOrderEnd(int pos) {
        if (ManagerLocalData.isUseSerialPort()) {
            int position = pos + 1;
            //发送获取累计水量
            byte[] commandTotal = SerialPortUtils.getReadWaterUsageC(position);
            //发送关闭供水开关
            byte[] commandClose = SerialPortUtils.getWaterValveC(position, false);
            //发送关闭储物柜锁
            byte[] commandLocker = SerialPortUtils.getLockerC(position, false);
            if (ManagerLocalData.isSupportLocker()) {
                addCommand(
                        new SerialCommandEntity(commandClose, SerialPortUtils.TYPE_COMMAND_WATER_CLOSE),
                        new SerialCommandEntity(commandTotal, SerialPortUtils.TYPE_COMMAND_WATER_READ_USAGE),
                        new SerialCommandEntity(commandLocker, SerialPortUtils.TYPE_COMMAND_LOCKER_CLOSE));
            } else {
                addCommand(
                        new SerialCommandEntity(commandClose, SerialPortUtils.TYPE_COMMAND_WATER_CLOSE),
                        new SerialCommandEntity(commandTotal, SerialPortUtils.TYPE_COMMAND_WATER_READ_USAGE));
            }
        } else {
            showBathPosWaterUsage(pos + 1, new DeviceWaterUsageEntity(0, false));
        }
    }

    //命令添加
    protected synchronized void addCommand(final SerialCommandEntity... commands) {
        commandList.addAll(Arrays.asList(commands));
    }

    //命令删除
    protected synchronized void removeTopCommand() {
        if (commandList != null && commandList.size() > 0)
            commandList.remove(0);
    }

    protected class controlCommandThread implements Runnable {

        @Override
        public void run() {
            try {
                //当前命令发送未收到回复计时
                int timeOutCommand = 0;
                while (isActivityLive && isSerialPortRun) {
                    if (isCommandRun) {
                        timeOutCommand++;
                    } else {
                        timeOutCommand = 0;
                    }
                    //当大于200ms时，自动解锁命令发送，防止一直未收到回复
                    if (timeOutCommand >= 50) {
                        timeOutCommand = 0;
                        isCommandRun = false;
                    }
                    //当前无命令执行
                    if (!isCommandRun && commandList != null && commandList.size() > 0) {
                        isCommandRun = true;
                        final byte[] command = commandList.get(0).getCommand();
                        boolean isTest = commandList.get(0).isTest();
                        serialPortPresenter().sendCommand(command, isTest);
                        CommonUtils.w("发送开启洗浴命令：" + new Gson().toJson(commandList.get(0)));
                        StringBuilder builder = new StringBuilder();
                        String newLine = "\r\n";
                        builder.append("================================================================================================").append(newLine);
                        builder.append("Serial:command***********data:").append(new Gson().toJson(commandList.get(0))).append(newLine);
                        CommonUtils.saveLocalDailyLog(getRealTime(), builder.toString(), ConstantCore.LOG_SERIAL_PATH);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                itemSerialSend.setText(new Gson().toJson(command));
                            }
                        });
                        removeTopCommand();
                    }
                    Thread.sleep(10);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                CommonUtils.saveLocalDailyLog(getRealTime(), "controlCommandThread_error" + e.getMessage(), ConstantCore.LOG_SERIAL_PATH);
            }
        }
    }

    /********************************* 串口相关 **************************************/
    @Override
    public void onReceiveData(Boolean isSuccess, final String parseType, final SerialDataEntity data) {
        String x = parseType + "\n" + new Gson().toJson(data.getBuffer());
        isCommandRun = false;
        if (isSuccess) {
            switch (parseType) {
                case SerialPortParse.PARSE_TEMPERATURE: {
                    DeviceTemperatureEntity temperatureEntity = SerialPortParse.parseTemperature(data);
                    showBathPosTemperature(temperatureEntity);
                    x = x + "\n" + new Gson().toJson(temperatureEntity);
                }
                break;
                case SerialPortParse.PARSE_WATER_USAGE: {
                    //localSendMessage(APP_TOAST, "结束洗浴串口信息返回成功");
                    int pos = SerialPortParse.parseAddressPos(data);
                    DeviceWaterUsageEntity waterUsageEntity = SerialPortParse.parseWaterUsage(data);
                    if (waterUsageEntity.getWaterUsage() >= 32768) {
                        waterUsageEntity.setWaterUsage(0);
                        //报故障
                        //bathPosPresenter().updateBathPosState(pos - 1, ReqConstant.BATH_POS_STATE_FAULT, 0, 0);
                    }
                    //结束订单
                    showBathPosWaterUsage(pos, waterUsageEntity);
                }
                break;
                case SerialPortParse.PARSE_CLEAR_WATER: {

                }
                break;
                case SerialPortParse.PARSE_WATER_VALVE: {
                    DeviceControlEntity waterValveEntity = SerialPortParse.parseWaterValve(data);
                    CommonUtils.w(new Gson().toJson(waterValveEntity));
                    x = x + "\n" + new Gson().toJson(waterValveEntity);
                }
                break;
                case SerialPortParse.PARSE_CONTROL_VALVE: {

                }
                break;
                case SerialPortParse.PARSE_LOCKER: {
                    DeviceControlEntity waterValveEntity = SerialPortParse.parseWaterValve(data);
                    CommonUtils.w(new Gson().toJson(waterValveEntity));
                }
                break;
                case SerialPortParse.PARSE_CONTROL_LOCKER: {

                }
                break;
                case SerialPortParse.PARSE_ERROR: {

                }
                break;
            }
            final String y = x;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    itemSerialReceiver.setText(y);
                }
            });
        } else {
            CommonUtils.w("error");
        }
    }

    /********************************* 串口相关 **************************************/
    @Override
    public void onSendDataSuccess() {
        //localSendMessage(APP_TOAST,"串口命令发送成功");
    }

    @Override
    public void onConnectSuccess() {
        //localSendMessage(APP_TOAST,"串口开启成功");
        isCommandRun = false;
        isSerialPortRun = true;
        //开始发送串口命令线程
        ThreadPoolUtils.execute(new controlCommandThread());
    }

    @Override
    public void onCloseSuccess() {
        isCommandRun = false;
        isSerialPortRun = false;
        if (isResetSerialPort) {
            openSerialPort();
        }
    }

    @Override
    public void onError(String errorMsg) {
        ToastUtils.show(errorMsg);
    }

    //测试串口部分

    @OnClick({R.id.item_serial_back_img, R.id.item_serial_back_txt,
            R.id.item_btn_clear_water_usage, R.id.item_btn_get_water_usage,
            R.id.item_btn_open_pos_water_valve, R.id.item_btn_close_pos_water_valve,
            R.id.item_btn_open_pos_locker, R.id.item_btn_close_pos_locker,
            R.id.item_btn_get_water_valve_state, R.id.item_btn_get_locker_state,
            R.id.item_btn_get_temperature})
    public void onSerialViewClicked(View view) {
        int pos = ManagerLocalData.getTestSerialPos() + 1;
        switch (view.getId()) {
            case R.id.item_serial_back_img:
            case R.id.item_serial_back_txt:
                itemShowSerialView.setVisibility(View.GONE);
                itemSettingRootView.setVisibility(View.VISIBLE);
                break;
            case R.id.item_btn_clear_water_usage: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getClearWaterUsageC(pos);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_WATER_CLEAR_USAGE, true));
                }
            }
            break;
            case R.id.item_btn_get_water_usage: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getReadWaterUsageC(pos);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_WATER_READ_USAGE, true));
                }
            }
            break;
            case R.id.item_btn_open_pos_water_valve: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getWaterValveC(pos, true);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_WATER_OPEN, true));
                }
            }
            break;
            case R.id.item_btn_close_pos_water_valve: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getWaterValveC(pos, false);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_WATER_CLOSE, true));
                }
            }
            break;
            case R.id.item_btn_open_pos_locker: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getLockerC(pos, true);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_LOCKER_OPEN, true));
                }
            }
            break;
            case R.id.item_btn_close_pos_locker: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getLockerC(pos, false);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_LOCKER_CLOSE, true));
                }
            }
            break;
            case R.id.item_btn_get_water_valve_state: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getReadWaterValveStateC(pos);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_WATER_READ_USAGE, true));
                }
            }
            break;
            case R.id.item_btn_get_locker_state: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getReadLockerStateC(pos);
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_READ_LOCKER_STATE, true));
                }
            }
            break;
            case R.id.item_btn_get_temperature: {
                if (ManagerLocalData.isUseSerialPort()) {
                    byte[] command = SerialPortUtils.getReadTemperatureC;
                    addCommand(new SerialCommandEntity(command, SerialPortUtils.TYPE_COMMAND_READ_TEMP, true));
                }
            }
            break;
        }
    }

    @Override
    public void onSendCommand(int pos) {
        if (ManagerLocalData.isUseSerialPort()) {
            byte[] command = SerialPortUtils.getSetAddressC(pos);
            addCommand(new SerialCommandEntity(command, "getSetAddressC:" + pos));
        }
    }

    @BindView(R.id.item_serial_send)
    TextView itemSerialSend;
    @BindView(R.id.item_serial_receiver)
    TextView itemSerialReceiver;
}